# Copyright (c) 2011 anatanokeitai.com(sakurai_youhei)
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# 
# The Software shall be used for Younger than you, not Older.
# 

import os
import sys
import xml.dom.minidom
import mimetypes

import pysugarsync
from pysugarsync.exception import PySugarSyncError

folder_xml="""
<folder>
    <displayName>subFolder</displayName>
</folder>
"""

folder_dom=xml.dom.minidom.parseString(folder_xml)

file_xml="""
<file>
    <displayName>mypicture</displayName>
    <mediaType>image/jpeg</mediaType>
</file>"""

file_dom=xml.dom.minidom.parseString(file_xml)

  
def get_folder(url,parent=None):
  resp = pysugarsync.conn.do_get(url,{})
  dom=xml.dom.minidom.parseString(resp.read())
  resp.close()

  name=dom.getElementsByTagName("displayName")[0].firstChild.data
  created=dom.getElementsByTagName("timeCreated")[0].firstChild.data
  collections=dom.getElementsByTagName("collections")[0].firstChild.data
  files=dom.getElementsByTagName("files")[0].firstChild.data
  contents=dom.getElementsByTagName("contents")[0].firstChild.data
  
  folder = Folder(url,name,created,parent,collections,files,contents)
  return folder

class Entity(object):
  def __init__(self,url,name,parent,is_folder,is_file):
    self._url=url
    self.name=name
    self.parent=parent
    self.is_folder=is_folder
    self.is_file=is_file

  def delete(self):
    resp = pysugarsync.conn.do_delete(self._url,{})
    resp.close()

class Folder(Entity):
  def __init__(self,url,name,created,parent,collections,files,contents):
    Entity.__init__(self,url,name,parent,True,False)
    self.created=created
    self._collections=collections
    self._files=files
    self._contents=contents
    
  def __repr__(self):
    return '<Folder: %s (%s)>' % (self.name,self.created)

  def __str__(self):
    return '<Folder: %s (%s)>' % (self.name,self.created)

  def subfolders(self,start=0,max=500):
    additional_query=""
    if start>=0:
      additional_query+="&start=%d"%start
    if max>=0:
      additional_query+="&max=%d"%max

    resp = pysugarsync.conn.do_get(self._collections+additional_query,{})
    dom=xml.dom.minidom.parseString(resp.read())
    resp.close()

    if isinstance(pysugarsync.debug_level,int) and pysugarsync.debug_level>=2:
      sys.stderr.write("\n"+dom.toprettyxml()+"\n")

    folders=[]
    for collection in dom.getElementsByTagName("collection"):
      t=collection.attributes.get("type",None)
      if t and t.value=="folder":
        ref=collection.getElementsByTagName("ref")[0].firstChild.data
        folders.append(get_folder(ref,parent=self))
      else:
        print dom.toxml()
        raise PySugarSyncError("unexpected type %s"%t)
    
    return folders
    
  def files(self,start=0,max=500):
    additional_query=""
    if start>=0:
      additional_query+="&start=%d"%start
    if max>=0:
      additional_query+="&max=%d"%max

    resp = pysugarsync.conn.do_get(self._files+additional_query,{})
    dom=xml.dom.minidom.parseString(resp.read())
    resp.close()

    if isinstance(pysugarsync.debug_level,int) and pysugarsync.debug_level>=2:
      sys.stderr.write("\n"+dom.toprettyxml()+"\n")
    
    files=[]
    for f in dom.getElementsByTagName("file"):
      url=f.getElementsByTagName("ref")[0].firstChild.data
      name=f.getElementsByTagName("displayName")[0].firstChild.data
      modified=f.getElementsByTagName("lastModified")[0].firstChild.data
      size=f.getElementsByTagName("size")[0].firstChild.data
      mime=f.getElementsByTagName("mediaType")[0].firstChild.data
      try:
        data=f.getElementsByTagName("fileData")[0].firstChild.data
      except IndexError,e:
        data=None
      present_on_server=f.getElementsByTagName("presentOnServer")[0].firstChild.data
      files.append(File(url,name,modified,self,size,mime,data,present_on_server))
    
    return files
    
  def create_subfolder(self,name):
    folder_dom.getElementsByTagName("displayName")[0].firstChild.data=name
    resp = pysugarsync.conn.do_post(self._url,folder_dom.toxml(),{"content-type":"application/xml; charset=UTF-8"})
    resp.close()
    
  def rename(self,newname):
    folder_dom.getElementsByTagName("displayName")[0].firstChild.data=newname
    resp = pysugarsync.conn.do_put(self._url,folder_dom.toxml(),{"content-type":"application/xml; charset=UTF-8"})
    resp.close()
    self.name=newname

  def put_file(self,filename, mimetype=None):
    if not isinstance(filename,str):
      raise PySugarSyncError("invalid arguments. %s"% filename)
    try:
      if mimetype is None:
        mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'

      if isinstance(pysugarsync.debug_level,int) and pysugarsync.debug_level>=1:
        sys.stderr.write("%s(%s)"%(filename,mimetype))

      name = os.path.basename(filename)
      file_dom.getElementsByTagName("displayName")[0].firstChild.data \
              =name
      file_dom.getElementsByTagName("mediaType")[0].firstChild.data \
              =mimetype
        
      resp=pysugarsync.conn.do_post(self._url,file_dom.toxml(),{"content-type":"application/xml; charset=UTF-8"})
      resp.close()

      fp=open(filename,"rb")
      data=fp.read()
      fp.close()
      
      for f in self.files():
        if f.name==name:
          f.data(putdata=data)
    except IOError,e:
      raise e
      #raise PySugarSyncError("fail to upload file. %s"% filename)



class File(Entity):
  def __init__(self,url,name,modified,parent,size,mimetype,data,present_on_server):
    Entity.__init__(self,url,name,parent,False,True)
    self.modified = modified
    self.size=size
    self.mimetype=mimetytpe
    self._data=data
    self.present_on_server=present_on_server

  def __repr__(self):
    return '<File: %s (%s) %s %s>' % (self.name,self.modified,
                                                   self.mime,self.size)

  def __str__(self):
    return '<File: %s (%s) %s %s>' % (self.name,self.modified,
                                                   self.mime,self.size)

  def data(self,putdata=None):
    if putdata:
      resp = pysugarsync.conn.do_put(self._url+"/data",putdata,{"content-type":"application/octet-stream","content-length":len(putdata)})
      resp.close()
    else:
      resp = pysugarsync.conn.do_get(self._data,{})
      data = resp.read()
      resp.close()
      return data
      
  def rename(self,newname):
    file_dom.getElementsByTagName("displayName")[0].firstChild.data=newname
    file_dom.getElementsByTagName("mediaType")[0].firstChild.data=mimetype
    resp = pysugarsync.conn.do_put(self._url,file_dom.toxml(),{"content-type":"application/xml; charset=UTF-8"})
    resp.close()
    self.name=newname
